CGIs and WebStar 2
Volume Number: 11
Issue Number: 8
Column Tag: Internet Development
CGI Applications and WebSTAR 
Make your World Wide Web server sing and dance.
By Jon Wiederspan, jonwd@tjp.washington.edu
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
Last month I walked you through the basics of creating a CGI application (“CGI
Applications and WebSTAR: Have some fun with your World Wide Web server”). The
result was a framework that can be used to create almost any CGI application you can
think of. If you’re like me, though, having a “framework” is terribly frustrating
because it takes you right to the brink of being able to do what you want and then stops.
This month I’ll push you right over the edge as we plunge headlong into a real world
application of CGI programming.
Before we get into the meat of a new script, though, there are several
preliminary topics to cover. I will cover how to use existing OSAXes to speed up your
AppleScripts, how to get useful error replies, how to parse and decode the information
that is passed to the CGI application, and the basics of how FORM elements work. Once
all of that is covered you will be ready to tackle this month’s project, a CGI that allows
people to leave comments about your site (or whatever you want). Because I have
already crammed a ton of information into this article, I will not be repeating anything
from last month’s article. If you have not read it recently, you might want to give it a
quick review or at least keep it close at hand while you read this one.
This article is about writing CGI applications in AppleScript. When I refer to the
“script”, I am talking about the AppleScript code that will be compiled to become the
CGI application. When I refer to the “CGI application”, I am talking about the final
product. Until the script is properly compiled and saved (see last month) it is not a
CGI application. Just so nobody gets confused.
Gathering the Ingredients
AppleScript has one great drawback and that is speed. As your scripts gets larger you
will start measuring their running time in minutes instead of seconds. That is one of
the prices you commonly have to pay for an easy language and it is fine for many uses.
It is totally unacceptable for a CGI application, though. WebSTAR will only wait so long
before it just gives up and returns an error to the user (that is determined by the
timeout value that you set for WebSTAR).
The answer to the speed problem is an OSAX (Open Scripting Architecture
eXtension). OSAXes are code extensions to AppleScript that provide new commands.
These commands can speed up your scripts greatly by doing in one command what would
otherwise take many lines of AppleScript. An example could be an OSAX “caseConvert”
that would convert all lower case characters to upper case in a text string. There are
hundreds of OSAXes available on the Internet and various online services (see
“Uniform Resource Locator” for some good sites to check).
For this script I will be using four OSAXes:
ScriptTools OSAX v. 1.3.1 - This is a suite of OSAXes that provide new
commands for file management, sound handling, and more. We will only be using
the “File IO OSAX”, but I recommend installing the rest as well because of their
usefulness. (freeware)
Tokenize OSAX - This OSAX is part of the ACME Script Widgets collection. It takes
in a string of text and a list of one or more text delimiters. The delimiters are
used to break the text string up, then it deletes the delimiters and returns the
intervening text chunks as list items. As an example, using the delimiters
{“:”,“/”}, the text string
“http://www.uwtc.washington.edu/Computing/WWW/” would be returned as
the list {http}{www.uwtc.washington.edu}{Computing}{WWW}. (shareware,
$10)
DecodeURL OSAX - This OSAX takes in a string of text and decodes it according to
the guidelines in the URL specification. (freeware)
DePlus OSAX - This OSAX takes in a string of text and replaces all occurences of
the plus (+) character with a space. This is needed to take care of information
returned by Mosaic or NetScape Navigator. (freeware)
Installing OSAXes
To install these OSAXes, put them in a folder called “Scripting Additions” in the
“Extensions” folder in your System Folder. You cannot simply drag them over the
System folder, as you can with other system extensions. AppleScript loads OSAXes
dynamically, so it should not be necessary to restart your computer after adding new
OSAXes. I still recommend that you do restart if possible, though, to reduce the
chances of problems. Note: remember to take the OSAXes out of their folders before
moving them to the System folder.
All four of these OSAXes are available at
“ftp://ftp.first.com/pub/Mac/prog/as/”. Tokenize is part of an archive called
“ACME Script Widgets 2.0”. It is a good idea to download these OSAXes and have them
installed in your system before you read any further. That way you will have the
documentation on hand (I don’t have room here to cover specific commands) and be able
to jump right into the demonstration script..
Error Handling
Script Editor does a grammar and syntax check on your script every time you compile
it (save it as an application or as a compiled script or click on the “Check Syntax”
button). That doesn’t guarantee that the script will run without errors, though. It
only means that every command you have used is known to AppleScript and seems to
have the proper information provided for it. There is no way the Script Editor can
know about other problems that might occur at runtime, such as a timeout (if the
script takes too long to finish) or a failure to pass the proper information back to
WebSTAR. In addition, since AppleScript doesn’t type variables until they are used at
runtime, you could easily have the wrong type of information being passed to a
command, such as a variable containing a list instead of text.
Any one of these situations could result in an error in your CGI application.
Unfortunately, the error information that you get back from WebSTAR and the
operating system is not very useful. It may consist of an informative statement like
“CGI application failed” and an error code number or you may just get a blank page. In
addition, the error may cause your CGI application to post an error notification on the
server (a blinking icon in the menubar or a dialog box) and the CGI won’t work again
until you acknowledge the notification.
Luckily, AppleScript contains a construction for handling errors so they won’t
tie up your server. The compound statement looks like this:
try
[your code goes here]
on error errNum number errMsg
[error handling code goes here]
end try
If an error occurs in the code between the “try” and “on error” statements,
execution will pass to the “on error” handler. AppleScript always includes two pieces
of information for the handler, the description of the error (errMsg) and the error
number (errNum). This information allows you to take different actions depending on
the source of the error. Remember to keep the code in the error handler simple, since
an error can also occur there, in which case the script will stop.
The first thing we will do is take last month’s code and add the try construction.
For optimum protection, the try statement should be the very first line inside the
WWWΩsdoc event handler and the on error handler should be the last thing. The main
thing we want to do in the error handler is to return information to the user so that
they will know (1) what happened and (2) what to do about it and so WebSTAR won’t
be left waiting for a reply. The following code will do just that.
on error errMsg number errNum
set return_page to http_10_header
& "Error Page"
& "Error Encountered!
" & return
& "An error was encountered in this script." & return
set return_page to return_page
& "Error Message
" & return & errMsg & return
& "Error Number
" & return & errNum & return
& "Date
" & return & (current date) & return
set return_page to return_page
& "RPlease notify the webmaster at "
& "webmaster@your.domain.name" & " of this error."
& "
return return_page
end try
This code is pretty straightforward. First it builds an HTML text document to
return and store the information in return_page, then it returns return_page to
WebSTAR. Notice that the first thing added to return_page is the http_10_header. I
can’t say often enough how important it is to return a proper header for the client
(you may think I can, but I really can’t). The HTML document tells the user what the
error message was, the identification number of the error, and when the error
occurred. Then, at the bottom of the page, it tells the mail address to send the
information to (you will want to change this address, of course, to the real address for
the webmaster of your site). If the user has a mailto-capable client, they can mail the
information right from this error page.
Other Common Errors
The try construction won’t handle all errors, though. It only catches those that cause the CGI application to stop execution without crashing the entire server. Here
are the most common remaining problems that you might encounter.
1) The majority of problems are with incorrectly installed OSAXes. These usually
result in errors when you try to compile or “check” the script. The first thing
you should do when AppleScript complains about a command not found or an event
not available is to re-install the OSAXes and restart your computer (the one the
CGI application is running on).
2) The DecodeURL OSAX does not process 8-bit (international or double-byte) text
correctly. The CGI application will run but may return garbage or altered text
instead of the international characters. There is a modified DecodeURL OSAX from
Motoyuki Tanaka that correctly processes international text. The OSAX is
available from his home page at “http://mtlab.ecn.fpu.ac.jp/guruguru/
others/DecodeURL_8bits.hqx”.
3) It is important to remember is that all processing for this CGI ends when the
information is returned to the user. A CGI application is launched when WebSTAR
sends the proper Apple event to it and it ends when the reply to that event is sent
back by a return statement. Some people think they can save processing time by returning information quickly to the user then processing the rest of the
information. Nope.
4) WebSTAR will not wait around forever for a reply from your CGI application.
The amount of time it will wait (in seconds) is defined by the timeout value
setting for the server. If you suspect that your CGI application will take a long
time to process the information, remember to increase this setting. If WebSTAR
times out, it will return the -1701 error code, meaning that no reply was
returned from the CGI application.
Improved Error Reporting
There are many ways that the error handler could be improved, of course. You
could use the error number to provide a more informative error message for the user
or you could return the contents of some key variables to show their intermediate
values. You could also use another script (one that works) to automatically send a mail
message to yourself about the error so you don’t have to count on the user doing so or
log the information to disk. Be creative. Go wild. The world’s your oyster.
Figure 1: A sample form page
Forms
Now it is time to talk about “forms”, by which I mean HTML documents that contain
FORM elements. Forms allow you to gather input from your users by providing text
fields, checkboxes, lists, and other items which the user can manipulate. Every form
also contains a button so users can send the information in the form to the server.
Forms are very important because they are really the only way to get extensive user
interaction with your Web pages. The search interface is too limited for getting much
information and maps are even more so. Figure 1 shows what a form page might look
like.
The selection in Text 1 shows how the form portion in Figure 1 looks as HTML
text. This sample displays one type of input, the text field, but there are others such
as radio buttons, checkboxes, scrolling lists, and popup menus. There is not room here
to cover how to write the forms themselves, but any good HTML book will cover them
in detail. Instead, I will focus on two topics, how a form page interacts with a CGI
application (general) and how the form data is encoded before it is sent to a CGI
application (specific). I’m assuming in the following sections that you are already
familiar with interactions between a WWW client, WebSTAR, and CGI applications, as
outlined in my last article.
VALUE="" MAXLENGTH=40>
RYour comment:
COLS=60>R
Text 1: Sample form section of an HTML document
Processing Forms
Every form page has to have at least one SUBMIT-type input defined. This
presents a button (for graphical browsers) that allows the user to send the
information from the form fields off for processing by a CGI application. When the
button is clicked by the user, all of the information in every field is packaged together
into one large piece of form data to be sent off for processing. The very first tag in the
form section defines where the form data will go and what method will be used to send
it. The tag looks something like this:
The METHOD defines how the data in the form fields will be sent (in this case, using the POST method) and the ACTION provides a URL to the CGI application that will
receive and process the data. In most cases, like this one, the CGI application will be
on the same server as the form page that calls it, so the URL is just the path (relative